package tech.yunland.shop.web;

import com.moyuer.bsf.common.Pagination;
import com.moyuer.bsf.domain.model.User;
import com.moyuer.bsf.domain.service.UserService;
import com.moyuer.bsf.web.controller.BaseController;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import tech.yunland.shop.domain.model.ChargeBill;
import tech.yunland.shop.domain.model.ChargeBillEntry;
import tech.yunland.shop.domain.model.GoodsPackage;
import tech.yunland.shop.domain.service.ChargeBillService;
import tech.yunland.shop.domain.service.GoodsPackageService;

import java.math.BigDecimal;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * 充值控制器
 *
 * @author 王东阳<350456985@qq.com>
 */
@RestController
@RequestMapping(value = "/charge")
public class ChargeBillController extends BaseController {

    @Autowired
    private ChargeBillService chargeBillService;

    @Autowired
    private GoodsPackageService goodsPackageService;

    @Autowired
    private UserService userService;

    /**
     * 充值
     *
     * @param memberId       会员标识
     * @param goodsPackageId 优惠活动标识
     * @param received       实收金额
     * @param remark         备注
     */
    @RequestMapping(value = "/", method = RequestMethod.POST)
    public void addChargeBill(
            @RequestParam String memberId,
//            @RequestParam String handlersId,
            @RequestParam String goodsPackageId,
            @RequestParam BigDecimal received,
            @RequestParam(required = false) BigDecimal quantity,
            @RequestParam(required = false) String remark,
            @RequestParam(required = false) Integer payment) {

        Set<String> errors = new HashSet<String>();

        if (quantity == null) {
            quantity = BigDecimal.ONE;
        }

        GoodsPackage goodsPackage = goodsPackageService.get(goodsPackageId);
        if (goodsPackage == null) {
            errors.add("优惠活动不存在");
        }
        else if (goodsPackage.getState() < 1) {
            errors.add("优惠活动未上架");
        }

        User member = userService.get(memberId);
        if (member == null) {
            errors.add("会员不存在");
        }
        else if (member.getState() < 0) {
            errors.add("会员已销户");
        }

        if (errors.size() > 0) {
            throw new RuntimeException(StringUtils.join(errors, ", "));
        }

        ChargeBill bill = new ChargeBill();
        bill.setMember(member);
        bill.setMemberId(memberId);
        bill.setOrgan(primaryOrgan);
        bill.setCreator(currentUser);
        bill.setReceivable(goodsPackage.getPrice().multiply(quantity));
        bill.setReceived(received);
        bill.setPayment(payment);//设置支付方式
//        bill.setHandlers(handlersId);
        bill.setRemark(StringUtils.trimToNull(remark));

        ChargeBillEntry entry = new ChargeBillEntry();
        entry.setOwner(bill);
        entry.setGoodsPackage(goodsPackage);
        entry.setQuantity(quantity);
        entry.setPrice(goodsPackage.getPrice());
        entry.setAmount(received);

        Set<ChargeBillEntry> entries = new HashSet<ChargeBillEntry>();
        entries.add(entry);

        bill.setEntries(entries);

        chargeBillService.addAndValidate(bill);

        saveLog("会员 [" + member.getName() + "] 购买优惠活动 [" + goodsPackage.getName() + "]");
    }

    /**
     * 根据 id 获取充值
     *
     * @param id
     * @return ChargeBill
     */
    @RequestMapping(value = "/{id}", method = RequestMethod.GET)
    public ChargeBill get(@PathVariable String id) {

        return chargeBillService.get(id);
    }

    /**
     * 根据 id 获取充值分录
     *
     * @param id
     * @return
     */
    @RequestMapping(value = "/entry/{id}", method = RequestMethod.GET)
    public ChargeBillEntry getCBE(@PathVariable String id) {
        return chargeBillService.getCBE(id);
    }

    /**
     * 根据 id 标记删除充值
     *
     * @param id
     * @return void
     */
    @RequestMapping(value = "/{id}", method = RequestMethod.DELETE)
    public void delete(@PathVariable String id) {
        ChargeBill chargeBill = chargeBillService.get(id);

        chargeBillService.delete(id);

        saveLog("删除充值记录成功，单号为：[" + chargeBill.getSn() + "]");
    }

    /**
     * 查询未创建和生效单据
     *
     * @param param
     * @param creatorIds
     * @param page
     * @param rows
     * @return
     */
    @RequestMapping(value = "/", method = RequestMethod.GET)
    public Pagination<ChargeBill> getResultInfos(
            @RequestParam(required = false) String param,
            @RequestParam(required = false) List<Integer> states,
            @RequestParam(required = false) String[] creatorIds,
            @RequestParam(required = false) Integer page,
            @RequestParam(required = false) Integer rows) {

        Pagination<ChargeBill> result = new Pagination<ChargeBill>(page, rows);
        int startIdx = result.getStartIdx();

        int count = chargeBillService.getResultSize(param, states, creatorIds, organIds);
        List<ChargeBill> records = chargeBillService.getResultInfos(param, states, creatorIds, startIdx, rows,
                organIds);

        result.setCount(count);
        result.setRecords(records);

        return result;
    }

    /**
     * 查询单据
     *
     * @param ownerId
     * @param goodsPackageId
     * @param page
     * @param rows
     * @return
     */
    @RequestMapping(value = "/entry/", method = RequestMethod.GET)
    public Pagination<ChargeBillEntry> getResultInfosCBE(
            @RequestParam(required = false) String ownerId,
            @RequestParam(required = false) String goodsPackageId,
            @RequestParam(required = false) Integer page,
            @RequestParam(required = false) Integer rows) {

        Pagination<ChargeBillEntry> result = new Pagination<ChargeBillEntry>(page, rows);
        int startIdx = result.getStartIdx();

        int count = chargeBillService.getResultSizeCBE(ownerId, goodsPackageId);
        List<ChargeBillEntry> records = chargeBillService.getResultInfoCBE(ownerId, goodsPackageId, startIdx, rows);

        result.setCount(count);
        result.setRecords(records);

        return result;
    }
}
